package org.weishe.weichat.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
import java.util.HashSet;

import org.weishe.weichat.bean.Attachment;
import org.weishe.weichat.wifi.foregin.FileInfo;
import org.weishe.weichat.wifi.foregin.GlobalConsts;
import org.weishe.weichat.wifi.foregin.Settings;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class FileUtil {
	private static String path = "";
	static {
		if (Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED)) {
			path = Environment.getExternalStorageDirectory() + "/QQ";
		} else {
			path = Environment.getDataDirectory().getAbsolutePath() + "/QQ";
		}
	}

	public static String getRecentChatPath() {
		File file = new File(path + "/RecentChat/");
		if (!file.exists()) {
			file.mkdirs();
		}
		return path + "/RecentChat/";
	}

	public static String getWaterPhotoPath() {
		File file = new File(path + "/WaterPhoto/");
		if (!file.exists()) {
			file.mkdirs();
		}
		return path + "/WaterPhoto/";
	}

	// //////////////////////////////////////////////////////////
	private static String ANDROID_SECURE = "/mnt/sdcard/.android_secure";

	private static final String LOG_TAG = "Util";

	public static boolean isSDCardReady() {
		return Environment.getExternalStorageState().equals(
				Environment.MEDIA_MOUNTED);
	}

	// if path1 contains path2
	public static boolean containsPath(String path1, String path2) {
		String path = path2;
		while (path != null) {
			if (path.equalsIgnoreCase(path1))
				return true;

			if (path.equals(GlobalConsts.ROOT_PATH))
				break;
			path = new File(path).getParent();
		}

		return false;
	}

	public static String makePath(String path1, String path2) {
		if (path1.endsWith(File.separator))
			return path1 + path2;

		return path1 + File.separator + path2;
	}

	public static String getSdDirectory() {
		return Environment.getExternalStorageDirectory().getPath();
	}

	public static boolean isNormalFile(String fullName) {
		return !fullName.equals(ANDROID_SECURE);
	}

	public static FileInfo GetFileInfo(String filePath) {
		File lFile = new File(filePath);
		if (!lFile.exists())
			return null;

		FileInfo lFileInfo = new FileInfo();
		lFileInfo.canRead = lFile.canRead();
		lFileInfo.canWrite = lFile.canWrite();
		lFileInfo.isHidden = lFile.isHidden();
		lFileInfo.fileName = FileUtil.getNameFromFilepath(filePath);
		lFileInfo.ModifiedDate = lFile.lastModified();
		lFileInfo.IsDir = lFile.isDirectory();
		lFileInfo.filePath = filePath;
		lFileInfo.fileSize = lFile.length();
		return lFileInfo;
	}

	public static FileInfo GetFileInfo(File f, FilenameFilter filter,
			boolean showHidden) {
		FileInfo lFileInfo = new FileInfo();
		String filePath = f.getPath();
		File lFile = new File(filePath);
		lFileInfo.canRead = lFile.canRead();
		lFileInfo.canWrite = lFile.canWrite();
		lFileInfo.isHidden = lFile.isHidden();
		lFileInfo.fileName = f.getName();
		lFileInfo.ModifiedDate = lFile.lastModified();
		lFileInfo.IsDir = lFile.isDirectory();
		lFileInfo.filePath = filePath;
		if (lFileInfo.IsDir) {
			int lCount = 0;
			File[] files = lFile.listFiles(filter);

			// null means we cannot access this dir
			if (files == null) {
				return null;
			}

			for (File child : files) {
				if ((!child.isHidden() || showHidden)
						&& FileUtil.isNormalFile(child.getAbsolutePath())) {
					lCount++;
				}
			}
			lFileInfo.Count = lCount;

		} else {

			lFileInfo.fileSize = lFile.length();

		}
		return lFileInfo;
	}

	/*
	 * 采用了新的办法获取APK图标，之前的失败是因为android中存在的一个BUG,通过 appInfo.publicSourceDir =
	 * apkPath;来修正这个问题，详情参见:
	 * http://code.google.com/p/android/issues/detail?id=9151
	 */
	public static Drawable getApkIcon(Context context, String apkPath) {
		PackageManager pm = context.getPackageManager();
		PackageInfo info = pm.getPackageArchiveInfo(apkPath,
				PackageManager.GET_ACTIVITIES);
		if (info != null) {
			ApplicationInfo appInfo = info.applicationInfo;
			appInfo.sourceDir = apkPath;
			appInfo.publicSourceDir = apkPath;
			try {
				return appInfo.loadIcon(pm);
			} catch (OutOfMemoryError e) {
				Log.e(LOG_TAG, e.toString());
			}
		}
		return null;
	}

	public static String getExtFromFilename(String filename) {
		int dotPosition = filename.lastIndexOf('.');
		if (dotPosition != -1) {
			return filename.substring(dotPosition + 1, filename.length());
		}
		return "";
	}

	public static String getNameFromFilename(String filename) {
		int dotPosition = filename.lastIndexOf('.');
		if (dotPosition != -1) {
			return filename.substring(0, dotPosition);
		}
		return "";
	}

	public static String getPathFromFilepath(String filepath) {
		int pos = filepath.lastIndexOf('/');
		if (pos != -1) {
			return filepath.substring(0, pos);
		}
		return "";
	}

	public static String getNameFromFilepath(String filepath) {
		int pos = filepath.lastIndexOf('/');
		if (pos != -1) {
			return filepath.substring(pos + 1);
		}
		return "";
	}

	// return new file path if successful, or return null
	public static String copyFile(String src, String dest) {
		File file = new File(src);
		if (!file.exists() || file.isDirectory()) {
			Log.v(LOG_TAG, "copyFile: file not exist or is directory, " + src);
			return null;
		}
		FileInputStream fi = null;
		FileOutputStream fo = null;
		try {
			fi = new FileInputStream(file);
			File destPlace = new File(dest);
			if (!destPlace.exists()) {
				if (!destPlace.mkdirs())
					return null;
			}

			String destPath = FileUtil.makePath(dest, file.getName());
			File destFile = new File(destPath);
			int i = 1;
			while (destFile.exists()) {
				String destName = FileUtil.getNameFromFilename(file.getName())
						+ " " + i++ + "."
						+ FileUtil.getExtFromFilename(file.getName());
				destPath = FileUtil.makePath(dest, destName);
				destFile = new File(destPath);
			}

			if (!destFile.createNewFile())
				return null;

			fo = new FileOutputStream(destFile);
			int count = 102400;
			byte[] buffer = new byte[count];
			int read = 0;
			while ((read = fi.read(buffer, 0, count)) != -1) {
				fo.write(buffer, 0, read);
			}

			// TODO: set access privilege

			return destPath;
		} catch (FileNotFoundException e) {
			Log.e(LOG_TAG, "copyFile: file not found, " + src);
			e.printStackTrace();
		} catch (IOException e) {
			Log.e(LOG_TAG, "copyFile: " + e.toString());
		} finally {
			try {
				if (fi != null)
					fi.close();
				if (fo != null)
					fo.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		return null;
	}

	// does not include sd card folder
	private static String[] SysFileDirs = new String[] { "miren_browser/imagecaches" };

	public static boolean shouldShowFile(String path) {
		return shouldShowFile(new File(path));
	}

	public static boolean shouldShowFile(File file) {
		boolean show = Settings.instance().getShowDotAndHiddenFiles();
		if (show)
			return true;

		if (file.isHidden())
			return false;

		if (file.getName().startsWith("."))
			return false;

		String sdFolder = getSdDirectory();
		for (String s : SysFileDirs) {
			if (file.getPath().startsWith(makePath(sdFolder, s)))
				return false;
		}

		return true;
	}

	/*
	 * public static ArrayList<FavoriteItem> getDefaultFavorites(Context
	 * context) { ArrayList<FavoriteItem> list = new ArrayList<FavoriteItem>();
	 * list.add(new FavoriteItem(context.getString(R.string.favorite_photo),
	 * makePath(getSdDirectory(), "DCIM/Camera"))); list.add(new
	 * FavoriteItem(context.getString(R.string.favorite_sdcard),
	 * getSdDirectory())); //list.add(new
	 * FavoriteItem(context.getString(R.string.favorite_root),
	 * getSdDirectory())); list.add(new
	 * FavoriteItem(context.getString(R.string.favorite_screen_cap),
	 * makePath(getSdDirectory(), "MIUI/screen_cap"))); list.add(new
	 * FavoriteItem(context.getString(R.string.favorite_ringtone),
	 * makePath(getSdDirectory(), "MIUI/ringtone"))); return list; }
	 */

	public static boolean setText(View view, int id, String text) {
		TextView textView = (TextView) view.findViewById(id);
		if (textView == null)
			return false;

		textView.setText(text);
		return true;
	}

	public static boolean setText(View view, int id, int text) {
		TextView textView = (TextView) view.findViewById(id);
		if (textView == null)
			return false;

		textView.setText(text);
		return true;
	}

	// comma separated number
	public static String convertNumber(long number) {
		return String.format("%,d", number);
	}

	// storage, G M K B
	public static String convertStorage(long size) {
		long kb = 1024;
		long mb = kb * 1024;
		long gb = mb * 1024;

		if (size >= gb) {
			return String.format("%.1f GB", (float) size / gb);
		} else if (size >= mb) {
			float f = (float) size / mb;
			return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
		} else if (size >= kb) {
			float f = (float) size / kb;
			return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
		} else
			return String.format("%d B", size);
	}

	public static class SDCardInfo {
		public long total;

		public long free;
	}

	public static SDCardInfo getSDCardInfo() {
		String sDcString = android.os.Environment.getExternalStorageState();

		if (sDcString.equals(android.os.Environment.MEDIA_MOUNTED)) {
			File pathFile = android.os.Environment
					.getExternalStorageDirectory();

			try {
				android.os.StatFs statfs = new android.os.StatFs(
						pathFile.getPath());

				// 获取SDCard上BLOCK总数
				long nTotalBlocks = statfs.getBlockCount();

				// 获取SDCard上每个block的SIZE
				long nBlocSize = statfs.getBlockSize();

				// 获取可供程序使用的Block的数量
				long nAvailaBlock = statfs.getAvailableBlocks();

				// 获取剩下的所有Block的数量(包括预留的一般程序无法使用的块)
				long nFreeBlock = statfs.getFreeBlocks();

				SDCardInfo info = new SDCardInfo();
				// 计算SDCard 总容量大小MB
				info.total = nTotalBlocks * nBlocSize;

				// 计算 SDCard 剩余大小MB
				info.free = nAvailaBlock * nBlocSize;

				return info;
			} catch (IllegalArgumentException e) {
				Log.e(LOG_TAG, e.toString());
			}
		}

		return null;
	}

	/*
	 * public static void showNotification(Context context, Intent intent,
	 * String title, String body, int drawableId) { NotificationManager manager
	 * = (NotificationManager)
	 * context.getSystemService(Context.NOTIFICATION_SERVICE); Notification
	 * notification = new Notification(drawableId, body,
	 * System.currentTimeMillis()); notification.flags =
	 * Notification.FLAG_AUTO_CANCEL; notification.defaults =
	 * Notification.DEFAULT_SOUND; if (intent == null) { // FIXEME: category tab
	 * is disabled intent = new Intent(context, FileViewActivity.class); }
	 * PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
	 * intent, PendingIntent.FLAG_ONE_SHOT);
	 * notification.setLatestEventInfo(context, title, body, contentIntent);
	 * manager.notify(drawableId, notification); }
	 */

	public static String formatDateString(Context context, long time) {
		DateFormat dateFormat = android.text.format.DateFormat
				.getDateFormat(context);
		DateFormat timeFormat = android.text.format.DateFormat
				.getTimeFormat(context);
		Date date = new Date(time);
		return dateFormat.format(date) + " " + timeFormat.format(date);
	}

	/*
	 * public static void updateActionModeTitle(ActionMode mode, Context
	 * context, int selectedNum) { if (mode != null) {
	 * mode.setTitle(context.getString
	 * (R.string.multi_select_title,selectedNum)); if(selectedNum == 0){
	 * mode.finish(); } } }
	 */
	public static HashSet<String> sDocMimeTypesSet = new HashSet<String>() {
		{
			add("text/plain");
			add("text/plain");
			add("application/pdf");
			add("application/msword");
			add("application/vnd.ms-excel");
			add("application/vnd.ms-excel");
		}
	};

	public static String sZipFileMimeType = "application/zip";

	public static int CATEGORY_TAB_INDEX = 0;
	public static int SDCARD_TAB_INDEX = 1;

	public static int getFileType(File file) {

		String type = getExtensionName(file.getName());
		switch (type.toUpperCase()) {
		case "JPG":
			return Attachment.TYPE_JPG;

		case "PNG":
			return Attachment.TYPE_PNG;

		case "GIF":
			return Attachment.TYPE_GIF;

		case "DOC":
			return Attachment.TYPE_DOC;

		case "DOCX":
			return Attachment.TYPE_DOCX;

		case "PPT":
			return Attachment.TYPE_PPT;

		case "PPTX":
			return Attachment.TYPE_PPTX;

		case "XLS":
			return Attachment.TYPE_XLS;

		case "XLSX":
			return Attachment.TYPE_XLSX;

		case "PDF":
			return Attachment.TYPE_PDF;

		case "TXT":
			return Attachment.TYPE_TXT;

		case "RAR":
			return Attachment.TYPE_RAR;

		case "ZIP":
			return Attachment.TYPE_ZIP;

		case "MP3":
			return Attachment.TYPE_VOICE;

		case "WMA":
			return Attachment.TYPE_VOICE;

		case "MP4":
			return Attachment.TYPE_VIDEO;

		case "AVI":
			return Attachment.TYPE_VIDEO;

		case "RM":
			return Attachment.TYPE_VIDEO;
		case "RMVB":
			return Attachment.TYPE_VIDEO;

		case "MOV":
			return Attachment.TYPE_VIDEO;

		case "MKV":
			return Attachment.TYPE_VIDEO;

		default:
			return Attachment.TYPE_UNKNOWN;
		}
	}

	/*
	 * Java文件操作 获取文件扩展名
	 * 
	 * Created on: 2011-8-2 Author: blueeagle
	 */
	public static String getExtensionName(String filename) {
		if ((filename != null) && (filename.length() > 0)) {
			int dot = filename.lastIndexOf('.');
			if ((dot > -1) && (dot < (filename.length() - 1))) {
				return filename.substring(dot + 1);
			}
		}
		return filename;
	}

	/*
	 * Java文件操作 获取不带扩展名的文件名
	 * 
	 * Created on: 2011-8-2 Author: blueeagle
	 */
	public static String getFileNameNoEx(String filename) {
		if ((filename != null) && (filename.length() > 0)) {
			int dot = filename.lastIndexOf('.');
			if ((dot > -1) && (dot < (filename.length()))) {
				return filename.substring(0, dot);
			}
		}
		return filename;
	}
}
